package com.hsy.crm.web.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hsy.crm.web.domain.cm.App;
import com.hsy.crm.web.domain.cm.PageResult;
import com.hsy.crm.web.domain.cm.Unified;
import com.hsy.crm.web.domain.entity.ReceiptOrder;
import com.hsy.crm.web.domain.entity.VerificateOrder;
import com.hsy.crm.web.domain.entity.VerificateOrderDetail;
import com.hsy.crm.web.domain.po.verificate.VerifiOrderPagePo;
import com.hsy.crm.web.domain.po.verificate.VerificateOrderPagePo;
import com.hsy.crm.web.domain.po.verificate.VerificateOrderPo;
import com.hsy.crm.web.domain.vo.verificate.VerifiOrderPageVo;
import com.hsy.crm.web.domain.vo.verificate.VerificateInsertVo;
import com.hsy.crm.web.domain.vo.verificate.VerificateOrderPageVo;
import com.hsy.crm.web.mapper.VerificateOrderDetailMapper;
import com.hsy.crm.web.mapper.VerificateOrderMapper;
import com.hsy.crm.web.service.base.BaseService;
import com.hsy.crm.web.service.base.DataInitService;
import com.hsy.crm.web.utils.UuidUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class VerificateOrderService extends BaseService<VerificateOrder> {


    @Autowired
    VerificateOrderMapper verificateOrderMapper;

    @Autowired
    VerificateOrderDetailMapper verificateOrderDetailMapper;

    @Autowired
    ReceiptOrderService receiptOrderService;

    public Unified<VerificateOrder> insertVerificate(VerificateInsertVo vo){
        Unified<VerificateOrder> unified = new Unified<>();

        VerificateOrder order = vo.getOrder();
        order.setCustomerId(vo.getCustomerId());
        order.setStatus(App.Status.BC);
        order.setLoginUserId(vo.getLoginUserId());
        order.setLoginCompanyId(vo.getLoginCompanyId());
        order.setCode(DataInitService.getOrderCode());
        this.insert(order);
        this.insertOrderDetails(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
             examine(order);
        }

        unified.setData(order);
        return unified;
    }

    public Unified<VerificateOrder> updateVerificate(VerificateInsertVo vo){
        Unified<VerificateOrder> unified = new Unified<>();

        VerificateOrder order = vo.getOrder();
        order.setCustomerId(vo.getCustomerId());
        order.setLoginUserId(vo.getLoginUserId());
        order.setLoginCompanyId(vo.getLoginCompanyId());
        this.update(order);

        this.deleteOrderDetails(order);
        this.insertOrderDetails(vo);

        if( vo.getSaveType() == App.SaveType.EXAMINE ){
            examine(order);
        }

        unified.setData(order);
        return unified;
    }

    @Transactional
    public Unified<Integer> examine(VerificateOrder order) {
        VerificateOrder dbOrder = verificateOrderMapper.selectByPrimaryKey(order);
        dbOrder.setCustomerId(order.getCustomerId());
        return this.updateStatus(dbOrder,App.Status.SH);
    }

    @Transactional
    public Unified<Integer> doInvalid(VerificateOrder order) {
        VerificateOrder dbOrder = verificateOrderMapper.selectByPrimaryKey(order);
        dbOrder.setCustomerId(order.getCustomerId());
        return this.updateStatus(dbOrder,App.Status.BC);
    }

    @Transactional
    public Unified<Integer> deleteVerificate(VerificateOrder order) {
        verificateOrderMapper.deleteByPrimaryKey(order);
        this.deleteOrderDetails(order);
        return Unified.newInstance();
    }

    public PageResult<VerificateOrderPagePo> page(VerificateOrderPageVo vo) {
        Page page = PageHelper.startPage(vo.getPage(),vo.getLimit());
        PageResult<VerificateOrderPagePo> pageResult = new PageResult<>();
        pageResult.setRows(verificateOrderMapper.page(vo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    public PageResult<VerifiOrderPagePo> verifiPage(VerifiOrderPageVo vo) {
        Page page = PageHelper.startPage(vo.getPage(),vo.getLimit());
        PageResult<VerifiOrderPagePo> pageResult = new PageResult<>();
        if( vo.getPageType() == 1 ){
            pageResult.setRows(verificateOrderMapper.verifiPage_receipt(vo));
        }else{
            pageResult.setRows(verificateOrderMapper.verifiPage_order(vo));
        }
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    public Unified<VerificateOrderPo> getOrder(VerificateOrder order) {
        VerificateOrderPo po = new VerificateOrderPo();
        po.setOrder(verificateOrderMapper.getOrder(order));
        po.setDetails(verificateOrderMapper.getOrderDetails(order));
        return Unified.newInstance(po);
    }

    private Unified<Integer> updateStatus(VerificateOrder dbOrder,int status){
        List<VerificateOrderDetail> details = this.getOrderDetails(dbOrder);
        for( VerificateOrderDetail detail : details ){
            this.doVerificateOrderDetail(dbOrder,detail,status);
        }

        VerificateOrder updateOrder = new VerificateOrder();
        updateOrder.setId(dbOrder.getId());
        updateOrder.setCustomerId(dbOrder.getCustomerId());
        updateOrder.setStatus(status);
        verificateOrderMapper.updateByPrimaryKeySelective(updateOrder);
        return Unified.newInstance();
    }

    private void doVerificateOrderDetail(VerificateOrder dbOrder,VerificateOrderDetail detail,int status){
        if( detail.getType() == 1 ){
            doVerificateOrderDetailBefore(dbOrder,detail,status);
        }else if( detail.getType() == 2 ){
            doVerificateOrderDetailAfter(dbOrder,detail,status);
        }
    }

    private void doVerificateOrderDetailBefore(VerificateOrder dbOrder,VerificateOrderDetail detail,int status){
        switch (dbOrder.getType()){
            case App.VerificateType.YS_YS :
                this.doReceipt(dbOrder,detail,status);
                break;
            case App.VerificateType.YF_YF :
                this.doReceipt(dbOrder,detail,status);
                break;
            case App.VerificateType.YS_YF :
                this.doOrder(dbOrder,detail,status);
                break;
            case App.VerificateType.YIS_YS :
                this.doOrder(dbOrder,detail,status);
                break;
            case App.VerificateType.YIF_YF :
                this.doOrder(dbOrder,detail,status);
                break;
        }
    }

    private void doVerificateOrderDetailAfter(VerificateOrder dbOrder,VerificateOrderDetail detail,int status){
        switch (dbOrder.getType()){
            case App.VerificateType.YS_YS :
                this.doOrder(dbOrder,detail,status);
                break;
            case App.VerificateType.YF_YF :
                this.doOrder(dbOrder,detail,status);
                break;
            case App.VerificateType.YS_YF :
                this.doOrder(dbOrder,detail,status);
                break;
            case App.VerificateType.YIS_YS :
                break;
            case App.VerificateType.YIF_YF :
                break;
        }
    }

    private void doReceipt(VerificateOrder dbOrder,VerificateOrderDetail detail,int status){
        ReceiptOrder receiptOrder = new ReceiptOrder();
        receiptOrder.setCustomerId(dbOrder.getCustomerId());
        receiptOrder.setId(detail.getTargetId());
        if( status == App.Status.SH ){
            receiptOrder.setVerificateMoney(detail.getVerificateMoney());
        }else if( status == App.Status.BC ){
            receiptOrder.setVerificateMoney(-detail.getVerificateMoney());
        }
        verificateOrderMapper.updateReceipt(receiptOrder);
    }

    private void doOrder(VerificateOrder dbOrder,VerificateOrderDetail detail,int status){
        if( status == App.Status.SH ){
            receiptOrderService.updateOrderVerificateMoney(dbOrder.getCustomerId(),detail.getTargetId(),detail.getVerificateMoney());
        }else if( status == App.Status.BC ){
            receiptOrderService.updateOrderVerificateMoney(dbOrder.getCustomerId(),detail.getTargetId(),-detail.getVerificateMoney());
        }
    }

    private List<VerificateOrderDetail> getOrderDetails(VerificateOrder order){
        VerificateOrderDetail query = new VerificateOrderDetail();
        query.setVerificateOrderId(order.getId());
        query.setCustomerId(order.getCustomerId());
        return verificateOrderDetailMapper.select(query);
    }

    private void deleteOrderDetails(VerificateOrder order){
        VerificateOrderDetail delete = new VerificateOrderDetail();
        delete.setCustomerId(order.getCustomerId());
        delete.setVerificateOrderId(order.getId());
        verificateOrderDetailMapper.delete(delete);
    }

    private void insertOrderDetails(VerificateInsertVo vo){
        List<VerificateOrderDetail> details = vo.getDetails();
        for (VerificateOrderDetail detail : details){
            detail.setId(UuidUtils.getUuid());
            detail.setCustomerId(vo.getCustomerId());
            detail.setVerificateOrderId(vo.getOrder().getId());
            verificateOrderDetailMapper.insert(detail);
        }
    }

}
